package com.monitor.handle_exception.com.ex.receive;

import com.monitor.handle_exception.com.ex.cast.ConCast;
import com.monitor.handle_exception.com.ex.entity.DataPackage;
import com.monitor.handle_exception.com.ex.util.JsonUtil;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class DataPackageReceiver implements Runnable {
    private static final Logger log = LoggerFactory.getLogger(DataPackageReceiver.class);

    public static final BlockingQueue<DataPackage> exceptionQueue = new LinkedBlockingQueue<>(ConCast.Queue.EXCEPTION_QUEUE_SIZE);

    @Value("${linisten.port}")
    private static int port = 5537;

    @Override
    public void run() {
        DatagramSocket socket = null;
        try{
            socket = new DatagramSocket(port);
            byte[] buf = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buf,buf.length);
            while(true){
                socket.receive(packet);

                String ip = packet.getAddress().getHostAddress();
                String srcMsg = new String(packet.getData(),0,packet.getLength());
                int port = packet.getPort();
                log.info("收到来自 {} : {}的数据信息 {}",ip,port,srcMsg);

                DataPackage dataPackage = JsonUtil.string2Object(srcMsg, new TypeReference<DataPackage>() {});
                putMsg2Queue(dataPackage);
            }
        }catch (SocketException e){
            log.error("网络通信异常，{}",e);
        }catch (IOException e){
            log.error("数据接收异常,{}",e);
        }finally {
            if (socket != null){
                socket.close();
            }
        }

    }

    private void putMsg2Queue(DataPackage dataPackage){
        boolean success =false;
        switch (dataPackage.getType()){
            case ConCast.PackageType.TYPE_OF_EXCEPTION:
                success = exceptionQueue.offer(dataPackage);
                default:
                    log.error("未定义的消息类型 {} 消息错误",JsonUtil.obj2String(dataPackage));
        }
        if (!success){
            log.error("投放 {} 消息错误",JsonUtil.obj2String(dataPackage));
        }
    }
}
